/*******************************************************************************
 * Copyright:   Copyright (c) 2007. Hisilicon Technologies, CO., LTD.
 * Version:     V300R001B03
 * Filename:    fmClass.h
 * Description: Header file for fm Control Class.
 * History:
                1.Created by g00124340 on 2009/03/03
  
*******************************************************************************/

#ifndef _INC_FMCLASS_H
#define _INC_FMCLASS_H

#include "csp.h"
#include "csr_fm_reg.h"
#include "hisi6810_fm.h"
#include "hisi6810_kpc.h"

//------------------------------------------------------------------------------
// Defines
//------------------------------------------------------------------------------

#ifdef DEBUG

  // Debug zone bit positions
  #define ZONEID_INIT         0
  #define ZONEID_DEINIT       1
  #define ZONEID_OPEN         2
  #define ZONEID_CLOSE        3
  #define ZONEID_IOCTL        4
  #define ZONEID_POWERUP      5
  #define ZONEID_POWERDOWN    6
  #define ZONEID_THREAD       7
  #define ZONEID_TRANSFER     8
  #define ZONEID_FUNCTION     13
  #define ZONEID_WARN         14
  #define ZONEID_ERROR        15

  // Debug zone masks
  #define ZONEMASK_INIT       (1 << ZONEID_INIT)
  #define ZONEMASK_DEINIT     (1 << ZONEID_DEINIT)
  #define ZONEMASK_OPEN       (1 << ZONEID_OPEN)
  #define ZONEMASK_CLOSE      (1 << ZONEID_CLOSE)
  #define ZONEMASK_IOCTL      (1 << ZONEID_IOCTL)
  #define ZONEMASK_POWERUP    (1 << ZONEID_POWERUP)
  #define ZONEMASK_POWERDOWN  (1 << ZONEID_POWERDOWN)
  #define ZONEMASK_THREAD     (1 << ZONEID_THREAD)
  #define ZONEMASK_TRANSFER   (1 << ZONEID_TRANSFER)
  #define ZONEMASK_FUNCTION   (1 << ZONEID_FUNCTION)
  #define ZONEMASK_WARN       (1 << ZONEID_WARN)
  #define ZONEMASK_ERROR      (1 << ZONEID_ERROR)
 
  #define  ZONE_OPERATE    		(0x0000) 
  #define  ZONE_DEBUG			(0x0001)
  #define  ZONE_ERROR           (0x0001)
  #define  ZONE_WARN            (0x0002)
  #define  ZONE_FUNCTION        (0x0004)
  #define  ZONE_IOCTL           (0x0008)
 
#define FMDEBUGMSG(cond, printf_exp) \
  {if(((g_dwFMMSGMask)&(cond))){ NKDbgPrintfW(TEXT("[FM:%s]"),TEXT(__FUNCTION__));\
	if(ZONE_FUNCTION == ((g_dwFMMSGMask)&(cond)))\
	  { NKDbgPrintfW(TEXT("[I]"));}\
	else if(ZONE_WARN == ((g_dwFMMSGMask)&(cond)))\
	  { NKDbgPrintfW(TEXT("[W]"));}\
	else if(ZONE_ERROR == ((g_dwFMMSGMask)&(cond)))\
	  { NKDbgPrintfW(TEXT("[E]"));}\
	else if(ZONE_IOCTL == ((g_dwFMMSGMask)&(cond)))\
	  { NKDbgPrintfW(TEXT("[T]"));}\
	  NKDbgPrintfW printf_exp;}}

#else
  
   #define FMDEBUGMSG(cond,printf_exp)  (((cond)?(NKDbgPrintfW printf_exp),1:0))

#endif // DEBUG


#ifndef READ_REGISTER_ULONG
#define READ_REGISTER_ULONG(reg) (*(volatile unsigned long * const)(reg))
#endif

#ifndef WRITE_REGISTER_ULONG
#define WRITE_REGISTER_ULONG(reg, val) (*(volatile unsigned long * const)(reg)) = (val)
#endif


//#define FM_ENABLE_RDS

typedef int (*fnHciConnection)(void);

//------------------------------------------------------------------------------
// Functions
//------------------------------------------------------------------------------
// This function is the begining of Fm interrupt thread.
DWORD IntrThread(VOID *pContext);

//------------------------------------------------------------------------------
// Types
//------------------------------------------------------------------------------

class FMClass
{
public:

    // I2C CONSTRUCTOR/DESTRUCTOR METHODS
    FMClass(VOID);
    ~FMClass(VOID);

    // Last Operation Result
    BOOL IsLastActionOK(void)
    {
        return (iResult >= 0);
    }

    INT GetLastResult(void)
    {
        return iResult;
    }

    VOID SetLastResult(INT iErrNum)
    {
        iResult = iErrNum;
    }

    // FMClass Initialize
    BOOL    Initialize();

    // This function initialize the FM register.
    BOOL    FM_Initialize();
    // This function turn on FM.
    BOOL    FM_PowerOn();
    // This function turn off FM.
    BOOL    FM_PowerOff();
    // This function get FM power state.
    BOOL    FM_GetPowerState();
    // This function set FM channel mode.
    BOOL    FM_SetChannelMode(EFM_CHANNEL_MODE fmMode);
    // This function get FM channel mode.
    BOOL    FM_GetChannelMode(EFM_CHANNEL_MODE *pFmMode);
    // This function set FM channel frequence.
    BOOL    FM_SetChannel(UINT32 channel);
    // This function get FM channel frequence.
    BOOL    FM_GetChannel(UINT32 *pChannel);
	// This function get FM Rssi signal Range.
	BOOL	FM_GetRssiRange(UINT8 *pRssiRange);
    // This function set the space used for change channel frequence.
    BOOL    FM_SetSpace(EFM_SPACE space);
    // This function get the space used for change channel frequence.
    BOOL    FM_GetSpace(EFM_SPACE *pSpace);
    // This function change current channel frequence by adding or decreasing the space.
    BOOL    FM_ChannelChange(BOOL bIsUp);
    // This function set seeking level.
    BOOL    FM_SetSeekRSSI(UINT8 rssi);
    // This function get seeking level.
    BOOL    FM_GetSeekRSSI(UINT8 *pRssi);
    // This function seek a valid FM channel.
    BOOL    FM_Seek(BOOL bIsUp);
	// This function get current channel rssi.
    BOOL    FM_GetRSSI(UINT8 *pRssi);
    // This function set FM tone mode.
    BOOL    FM_SetToneMode(EFM_TONE_MODE mode);
    // This function get FM tone mode.
    BOOL    FM_GetToneMode(EFM_TONE_MODE *mode);
    // This function get FM mute state.
    BOOL    FM_IsMute(BOOL *pIsMute);
    // This function set FM mute state.
    BOOL    FM_Mute(BOOL bIsMute);
    // This function set FM channel mode.
    BOOL    FM_SetGain(EFM_VOLUME_GAIN ucGain);
    // This function get FM channel mode.
    BOOL    FM_GetGain(EFM_VOLUME_GAIN *ucGain);
    // This function check whether reset-FM finished or not.
    BOOL    FM_ResetFinished()
    {
		return TRUE;
	}
    // This function Set the 32K clock for FM seek and Set channel.
    BOOL    FM_Set32KClk(BOOL bOnOff);

private:
    
	// This function Set the DWORD value to the Registry.
    BOOL    SetRegistryDWORD(const HKEY hRoot, const TCHAR* const psKeyName, const TCHAR* const psValueName, const DWORD dwValue);
	// This function Get the DWORD value from the Registry.
	BOOL    GetRegistryDWORD(const HKEY hRoot, const TCHAR* const psKeyName, const TCHAR* const psValueName, DWORD *const pdwValue);
	// This function read FM register value through I2C bus by Compound mode.
	BOOL    FMReadRegCP(volatile UINT8 *pRegAddr, UINT8 ucLen);
    // This function read FM register value through I2C bus.
    BOOL    FMReadReg(UINT8 *pucData, UINT8 ucLen);
    // This function write FM register 8bits value through I2C bus.
    BOOL    FMWriteReg(UINT8 *pucData, UINT8 Length);
    // This function mute FM chip.
    BOOL    FM_MuteExecute(BOOL bIsMute);
    // FM Register Operation Critical Section
    CRITICAL_SECTION m_csFmRegisterLock;

    UINT32  m_MaxChannle;
    UINT32  m_MinChannle;
	UINT32  m_MinFrequency;

	UINT32  m_MonoSearchBorder;
	UINT32  m_StereoSearchBorder;

    // the value for change current channel
    UINT16  m_Space;

    // FM is power on or not
    BOOL    m_bIsPowOn;
    // FM channel mode is setted or not
    BOOL    m_bIsChanModeSet;
    // FM initialization channel is setted or not
    BOOL    m_bIsInitChanSet;
    // FM seek RSSI is setted or not
    BOOL    m_bIsSetRssi;
    // FM in seeking operation or not
    BOOL    m_bInSeeking;

    // FM Volume parameter
    EFM_VOLUME_GAIN     m_eFmGain;
    BOOL    m_bFmMute;

    // FM register
    WRITE_FM_REG m_FMReg_WR;

	READ_FM_REG  m_FMReg_RD;

    // Last Known Result
    INT iResult;

    // FM I2C module handle
    HANDLE  m_hI2cHandle;

};

#endif   // _INC_FMCLASS_H

